/**
 * 
 */
package core;

import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.StringTokenizer;

import util.NBGStrParser;
import NET.sourceforge.BplusJ.BplusJ.BplusTree;

/**
 * @author Xiaohui
 * 
 */

public class Matching {
	/**
	 * TODO connect candidate trajectories and intersect with query window
	 * @param oidset
	 * @param rawIndexer
	 * @param qParser
	 * @return matched oids
	 * @throws Exception
	 */
	static public Set<Integer> doExactMatch(Set<Integer> oidset,
			RawDataIndex rawIndexer, QueryParser qParser) throws Exception {
		System.out.println("Before exact matching, oid set size: "
				+ oidset.size());
		double qx1 = qParser.getQx1();
		double qy1 = qParser.getQy1();

		double qx2 = qParser.getQx2();
		double qy2 = qParser.getQy2();

		double t1 = qParser.getStartTime();
		double t2 = qParser.getEndTime();
		Set<Integer> matchedOid = new HashSet<Integer>();

		Rectangle2D qRect = new Rectangle2D.Double(qx1, qy1, qx2 - qx1, qy2
				- qy1);
		Iterator<Integer> it = oidset.iterator();
		BplusTree btp = rawIndexer.open();
		long start = System.currentTimeMillis();
		while (it.hasNext()) {
			int canOid = (Integer) it.next();
			if (btp.ContainsKey("" + canOid)) {
				String nbgdata = btp.get("" + canOid);
				StringTokenizer st = new StringTokenizer(nbgdata, ";");
				while (st.hasMoreElements()) {
					NBGStrParser rawDataParser = new NBGStrParser(st
							.nextToken());
					int lineOid = rawDataParser.getOid();
					int timepoint = rawDataParser.getTimepoint();

					if (timepoint >= t1 && timepoint <= t2) {
						// System.out.println("reach here "+lineOid);
						if (qRect.contains(new Point2D.Double(rawDataParser
								.getCurrPosx(), rawDataParser.getCurrPosy()))) {
							matchedOid.add(lineOid);
						}
					}
				}
			}

		}
		long end = System.currentTimeMillis();
		System.out.println("Exact Match(ms): " + (end - start));
		return matchedOid;
	}

	/**
	 * Check with raw data by exact geometry
	 * 
	 * @param objid
	 * @param queryParsers
	 * @throws Exception
	 */
	public static Set<Integer> doExactMatch(Set<Integer> objid,
			QueryParser qParser, String rawDataFile) throws Exception {
		// scan the data file for objid's exact geometry
		// check with query parser
		// put into result set if it is contained
		double qx1 = qParser.getQx1();
		double qy1 = qParser.getQy1();
		double qx2 = qParser.getQx2();
		double qy2 = qParser.getQy2();

		double t1 = qParser.getStartTime();
		double t2 = qParser.getEndTime();

		Set<Integer> matchedOid = new HashSet<Integer>();

		Rectangle2D qRect = new Rectangle2D.Double(qx1, qy1, qx2 - qx1, qy2
				- qy1);

		BufferedReader in;
		try {
			in = new BufferedReader(new FileReader(rawDataFile));
			String str;
			while ((str = in.readLine()) != null) {
				NBGStrParser rawDataParser = new NBGStrParser(str);
				int lineOid = rawDataParser.getOid();
				int timepoint = rawDataParser.getTimepoint();

				if (timepoint > t1 && timepoint < t2 && objid.contains(lineOid)) {
					// System.out.println("reach here "+lineOid);
					if (qRect.contains(new Point2D.Double(rawDataParser
							.getCurrPosx(), rawDataParser.getCurrPosy()))) {
						matchedOid.add(lineOid);
					}
				}
			}
			in.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return matchedOid;
	}

}
